<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>2-类的继承</title>
  </head>
  <body>
    <!-- **
      * 总结:
      *   1.类中的构造器不是必须写的，要对实例进行一下初始化的操作，如添加属性时才写。
      *   2.如果A类继承了B类，且A类中写了构造器，那么A类构造器中的super是必须要调用的。
      *   3.类中定义的方法，都是放在了类的原型对象上，供实例对象使用
     -->
    <script>
      // 创建一个person类
      class Person {
        // 构造器
        constructor(name, age) {
          // 构造器中的this 是谁?--> 类的实例对象
          this.name = name;
          this.age = age;
        }
        // 一般方法
        say() {
          // say 方法放在哪里? -->  类的原型对象上  供实例使用
          // 通过Person实例调用say时，say中的 this 就是 Person 实例
          console.log(`我的名字是:${this.name},我年龄是:${this.age}`);
        }
      }

      // 创建一个student类，继承于 Person 类
      class Student extends Person {
        constructor(name, age, grade) {
          // super 必须放在最上面
          super(name, age);
          this.grade = grade;
        }
        // 重写
        say() {
          // say 方法放在哪里? -->  类的原型对象上  供实例使用
          // 通过Person实例调用say时，say中的 this 就是 Person 实例
          console.log(
            `我的名字是:${this.name},我年龄是:${this.age},我读${this.grade}`
          );
        }
        study() {
          // study 方法放在哪里? -->  类的原型对象上  供实例使用
          // 通过Student实例调用study时，study中的 this 就是 Student 实例
          console.log('我在努力学习');
        }
      }

      const s1 = new Student('哈哈', 18, '大一');
      console.log(s1);
      s1.say();
      s1.study();
    </script>
  </body>
</html>
